<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/lil-gui.module.min.js"></script>
</head>

<body>
    <canvas id="canvas" style="width: 800px; height: 600px;"></canvas>
</body>

<script id="vertex-shader" type="nojs">
    attribute vec2 a_position;
    uniform vec2 u_resolution;
    void main() {
        vec2 zeroToOne = a_position / u_resolution;
        vec2 zeroToTwo = zeroToOne * 2.0;
        vec2 clipSpace = zeroToTwo - 1.0;
        gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
    }
</script>

<script id="flagment-shader" type="nojs">
    precision mediump float;
    uniform vec4 u_color;

    void main() {
        gl_FragColor = u_color;
    }
</script>

<script type="module">
    import { GUI } from './js/lil-gui.module.min.js';

    const gui = new GUI();

    function main() {
        var canvas = document.querySelector("#canvas");
        canvas.width = 800;
        canvas.height = 600;

        const gl = document.getElementById('canvas').getContext('webgl');
        if (!gl) {
            console.log('Failed to get the rendering context for WebGL');
            return;
        }

        const vertexShader = createShader(gl, gl.VERTEX_SHADER, document.getElementById('vertex-shader').text);
        const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, document.getElementById('flagment-shader').text);

        const shaderProgram = initShaderProgram(gl, vertexShader, fragmentShader);

        const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'a_position');

        const resolutionUniformLocation = gl.getUniformLocation(shaderProgram, 'u_resolution');

        const colorUniformLocation = gl.getUniformLocation(shaderProgram, "u_color");

        // attribute 需要从缓冲区中获取数据
        const positionBuffer = gl.createBuffer();

        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

        // 通过bufferData将数据传入缓冲区
        setRectangle(gl, 10, 10, 100, 60);

        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

        // 设置背景颜色蓝色
        gl.clearColor(0, 0, 0, 255);
        // gl.clearColor(0, 1, 1, 0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.useProgram(shaderProgram);

        gl.enableVertexAttribArray(positionAttributeLocation); // 开启attribute变量

        gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
        gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);


        // 告诉attribute变量从缓冲区中获取数据
        const size = 2; // 每次迭代运行提取两个单位数据
        const type = gl.FLOAT; // 每个单位的数据类型是32位浮点型
        const normalize = false; // 不需要归一化数据
        const stride = 0; // 0 = 移动单位数量 * 每个单位占用内存（sizeof(type)）
        var offset = 0; // 从缓冲区何处开始获取数据
        gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);

        const primitiveType = gl.TRIANGLES;
        var offset = 0;
        var count = 3;
        gl.drawArrays(primitiveType, offset, count);

        const resolutionSize = {
            width: gl.canvas.width,
            height: gl.canvas.height
        }

        let currentPos = {
            x: 10,
            y: 10,
            width: 100,
            height: 60
        }

        gui.add(currentPos, 'x', 0, resolutionSize.width - currentPos.width).name('X位置').onChange(() => {
            setRectangle(gl, currentPos.x, currentPos.y, currentPos.width, currentPos.height);
            gl.clearColor(0, 0, 0, 255);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(primitiveType, offset, count);
        })

        gui.add(currentPos, 'y', 0, resolutionSize.height - currentPos.height).name('Y位置').onChange(() => {
            setRectangle(gl, currentPos.x, currentPos.y, currentPos.width, currentPos.height);
            gl.clearColor(0, 0, 0, 255);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(primitiveType, offset, count);
        })
        gui.add(currentPos, 'width', 0, resolutionSize.width - currentPos.x).name('宽度').onChange(() => {
            setRectangle(gl, currentPos.x, currentPos.y, currentPos.width, currentPos.height);
            gl.clearColor(0, 0, 0, 255);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(primitiveType, offset, count);
        })
        gui.add(currentPos, 'height', 0, resolutionSize.height - currentPos.y).name('高度').onChange(() => {
            setRectangle(gl, currentPos.x, currentPos.y, currentPos.width, currentPos.height);
            gl.clearColor(0, 0, 0, 255);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(primitiveType, offset, count);
        })

    }

    function setRectangle(gl, x, y, width, height) {
        const x1 = x;
        const x2 = x + width;
        const y1 = y;
        const y2 = y + height;

        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
            x1, y1,
            x2, y1,
            x1, y2,
            x1, y2,
            x2, y1,
            x2, y2,
        ]), gl.STATIC_DRAW);
    }

    function createShader(gl, type, source) {
        const shader = gl.createShader(type);
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (success) {
            return shader;
        }
        gl.deleteShader(shader);
    }

    function initShaderProgram(gl, vertexShader, fragmentShader) {
        const shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader)
        gl.attachShader(shaderProgram, fragmentShader)
        gl.linkProgram(shaderProgram)
        var success = gl.getProgramParameter(shaderProgram, gl.LINK_STATUS);
        if (success) {
            return shaderProgram;
        }
        gl.deleteProgram(shaderProgram);
    }

    main();


</script>

</html>